package com.cskaoyan.javase._2inner._3local._1basic;

/**
 * 明确两个原则:
 *      1.局部内部类仍然是一个内部类,仍然遵循"好兄弟"原则
 *          在局部内部类当中可以任意放外围类成员,不受权限限制
 *          但是
 *          在外围类当中访问时,情况变了
 *          因为局部内部类仅在作用域内部类生效
 *          所以在外围类当中,就只能在装有局部内部类的作用域内部访问它
 *          别的位置访问不了
 *          当然这个访问,也不受权限限制.
 *
 *      2.局部内部类和外围类有什么关系呢?有联系吗?
 *          有关系,也没关系,要看情况
 *          以方法中的局部内部类为例
 *          如果是外围类成员方法中的局部内部类,
 *              该局部内部类对象会持有外围类对象的引用,类似于成员内部类对象
 *          如果是外围类静态成员方法中的局部内部类,
 *              该局部内部类对象不会持有外围类对象的引用,类似于静态内部类对象
 *
 * 局部内部类的访问特点，我们仍然主要从以下几个角度研究：
 *      局部内部类内部访问外围类
 *          要分两种情况:
 *              1.外围类成员方法中的局部内部类
 *                  该局部内部类对象会持有外围类对象的引用,所以可以直接访问外围类成员
 *                  如果出现同名
 *                  就用"外围类类名.this"指向外围类对象区分
 *                  这里和成员内部类当中访问外围类成员是一模一样的.
 *
 *              2.外围类静态成员方法中的局部内部类
 *                  没有外围类对象
 *                  需要创建外围类对象
 *                  该怎么访问就怎么访问
 *
 *      外围类访问局部内部类成员
 *           只能在装有局部内部类的作用域内部创建对象,才能够访问,不受权限限制
 *           其余位置访问不到
 *
 *      外部类访问局部内部类成员
 *            不能直接访问了,不是权限的问题,是真的不能直接访问
 *            但是也可以间接访问,因为方法内部的局部内部类,可以用方法,把该局部内部类的对象返回出来.
 *
 *      局部内部类访问外部类成员
 *          可以访问,创建对象访问,受权限限制
 *
 * @since 10:04
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*EnclosedClazz ec = new EnclosedClazz();
        ec.test();

        EnclosedClazz.testStatic();*/

        A a = new A();
        Object inner = a.test();
        // inner.b.sout

        IA ia = A.testStatic();
        ia.test();
    }
}

class A {
    public Object test() {
        class Inner {
            private int a = 10;
            int b = 10;
        }
        // Object类是Java中所有类的父类,内部类也继承Object
        return new Inner();
    }

    public static IA testStatic(){
        // 局部内部类Inner是IA接口的子类
        class Inner implements IA{
            @Override
            public void test() {
                System.out.println("6666");
            }
        }
        return new Inner();
    }
}
interface IA{
    void test();
}

class EnclosedClazz {
    int a;
    private int b = 10;
    static int c = 20;
    static final int D = 30;

    public static void testStatic() {
        class InnerClazz {
            int a;
            private int b = 100;
            static final int D = 300;

            public void testInner() {
                System.out.println(a);
                System.out.println(b);
                EnclosedClazz ec = new EnclosedClazz();
                System.out.println(ec.a);
                System.out.println(ec.b);
            }
        }
        InnerClazz ic = new InnerClazz();
        ic.testInner();
    }

    public void test() {
        // 成员方法内部,定义局部内部类
        class InnerClazz {
            int a;
            private int b = 100;
            static final int D = 300;

            public void testInner(int b) {
                System.out.println(a);
                System.out.println(EnclosedClazz.this.a);
                System.out.println(b);
                System.out.println(this.b);
                System.out.println(EnclosedClazz.this.b
                );
            }
        }
        InnerClazz ic = new InnerClazz();
        System.out.println(ic.a);
        System.out.println(ic.b);
    }
}
